package algorithmicFoundation.homework.day2;

import edu.princeton.cs.algs4.StdRandom;
import edu.princeton.cs.algs4.StdStats;

/**
 * 渗流统计
 * the value of the percolation threshold via Monte Carlo simulation.
 *
 * @author 86155
 * @date 2025/07/30
 */
public class PercolationStats {


    /**
     * 实验次数
     */
    private int T;

    /**
     * 阈值集合
     */
    private double[] data;

    /**
     * 阈值样本平均值
     */
    private double mean = 0.0;

    /**
     * 阈值样本标准差
     */
    private double s = 0.0;

    /**
     * 总的网格数量
     */
    private double size;

    /**
     * 独立性检验
     * perform independent trials on an n-by-n grid
     *
     * @param n      n 网格大小
     * @param trials 试验次数
     */
    public PercolationStats(int n, int trials) {
        if (n <= 0 || trials <= 0) {
            // 不合法
            throw new IllegalArgumentException("n must bigger than 0");
        }
        this.T = trials;
        this.size = n * n;
        //初始化阈值集合
        data = new double[trials];

        //填充data
        //实验次数
        for (int i = 0; i < trials; i++) {
            Percolation percolation = new Percolation(n);
            //如果渗流就退出
            while (!percolation.percolates()){
                //随机坐标开放
                int x = StdRandom.uniformInt(1,n + 1);
                int y = StdRandom.uniformInt(1,n + 1);
                percolation.open(x,y);
            }
            //计算P值：也就是渗流的概率
            this.data[i] = percolation.numberOfOpenSites() / this.size;
        }
    }

    /**
     * 平均值
     * sample mean of percolation threshold
     *
     * @return double
     */
    public double mean() {
        if (this.mean != 0.0) {
            return this.mean;
        }
        //计算一下再返回
        this.mean = StdStats.mean(this.data);
        return this.mean;
    }

    /**
     * stddev
     * sample standard deviation of percolation threshold
     *
     * @return double
     */
    public double stddev() {
        if (this.s != 0.0) {
            return this.s;
        }
        //计算标准差
        this.s = StdStats.stddev(this.data);
        return this.s;
    }

    /**
     * low endpoint of 95% confidence interval
     *
     * @return double
     */
    public double confidenceLo() {
        //假设 T 足够大 (比如至少 30), 下面给出了渗流阈值的 95% 置信区间：
        return this.mean - (1.96 * this.s / (Math.sqrt(this.T)));
    }

    /**
     * high endpoint of 95% confidence interval
     *
     * @return double
     */
    public double confidenceHi() {
        return this.mean + (1.96 * this.s / (Math.sqrt(this.T)));
    }


    public static void main(String[] args) {
        PercolationStats percolationStats = new PercolationStats(2, 10000);
        System.out.println(percolationStats.mean());
        System.out.println(percolationStats.stddev());
        System.out.println(percolationStats.confidenceLo() + ","+percolationStats.confidenceHi());
    }

}